home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / graphics / vgafx.zip / VGA_FX.DOC < prev   
Text File  |  1989-10-19  |  32KB  |  782 lines

  1.                 VGA TEXT ATTRIBUTES AND SPECIAL EFFECTS
  2.  
  3.                             by Chris Dunford
  4.  
  5.  
  6. While working on a project recently, I realized that I didn't know very
  7. much about how VGA text attributes work.  I knew that there wasn't a
  8. simple one-to-one relationship between attribute numbers and colors, but
  9. that's about it.  So, I did a little research and fooling around, and
  10. found that lots of interesting effects are possible.  You can draw
  11. people's attention to important screen information in ways more (and
  12. less!) subtle than simply flashing it on and off or using intensified
  13. colors.  For example, you can have colors that gradually shade from
  14. normal to high intensity and back, "pulsing" on the screen; you can
  15. display text that changes from one color to another (gradually shading
  16. from blue to red and back, for example); you can soften blinking by
  17. having the color "fade" rather than just disappear.  And, there are some
  18. things you can do under software control that can't be done with the
  19. usual hardware attributes; for example, you can use flashing
  20. backgrounds, or you can using flashing foregrounds without sacrificing
  21. high intensity backgrounds.  These can be done very efficiently, without
  22. the need to change the attributes of individual characters.
  23.  
  24. This document is an attempt to share some of what I learned; it
  25. explains how VGA text attributes work, and how these effects are
  26. possible.  The archive that contains this document should also contain
  27. a demo program and a linkable object module (with source) that allow
  28. you to use the effects in your own programs.  You might want to do a
  29. quick run of DEMO1 to see some of the possible effects in action.
  30.  
  31.  
  32. What's different with the VGA?
  33. ------------------------------
  34. The CGA implemented a direct relationship between a 4-bit attribute and
  35. a color.  Each attribute mapped to one color, and the color could not be
  36. changed.
  37.  
  38. That changed with the EGA (which had palette registers to play with),
  39. and changed again, radically, with the VGA.  The attribute number
  40. specifies the displayed color very indirectly; it is combined with bits
  41. and pieces of 5 different internal VGA registers before it appears on
  42. the screen as one of the 262,144 possible colors.  There are therefore
  43. several ways to change a character's color other than by changing its
  44. attribute.  And, of course, if you change the way an attribute is
  45. displayed, all characters with that attribute are affected.  Thus, it is
  46. possible to "design" attributes with interesting effects, and to alter
  47. the way entire screen fields are displayed very efficiently.
  48.  
  49.  
  50. Mapping attributes to colors
  51. ----------------------------
  52. Before we start, let me note that we are working here with 4-bit
  53. attributes.  The 8-bit attribute that's associated with a character is,
  54. of course, two 4-bit attributes: one for the foreground, and one for the
  55. background.  This document discusses how these 4-bit attributes become
  56. colors; everything here applies equally to foreground and background
  57. attributes (thus it is possible to use flashing backgrounds, etc.)
  58.  
  59. Screen colors in text modes are controlled by the VGA's attribute
  60. controller.  In one of its two modes (the one that the PS/2 BIOS sets
  61. by default), here is how a color is selected by an attribute:
  62.  
  63.                  AND
  64.     attribute |-------| color plane enable register
  65.                   |
  66.                   | selects
  67.                   |
  68.          palette register 0-15     color select register
  69.                   |                         |
  70.                   |                         |
  71.                   | bits 0-5       bits 6-7 |
  72.                   +------------+------------+
  73.                                |
  74.                                |      AND
  75.                                +-------+--------video DAC mask register
  76.                                        |
  77.                                        | selects
  78.                                        |
  79.                           video DAC color register 0-255
  80.  
  81. This appears complex, but it can be simplified.  First, notice the two
  82. logical AND operations.  Since both the color plane enable register and
  83. the video DAC mask register normally contain all ones, they tend to drop
  84. out of the picture, resulting in:
  85.  
  86.               attribute 0-15
  87.                   |
  88.                   | selects
  89.                   |
  90.          palette register 0-15     color select register
  91.                   |                         |
  92.                   |                         |
  93.                   | bits 0-5       bits 6-7 |
  94.                   +------------+------------+
  95.                                |
  96.                                | selects
  97.                                |
  98.                  video DAC color register 0-255
  99.  
  100. The 4-bit attribute (0-15) selects one of the 16 palette registers.  The
  101. palette register contains a number.  This number is combined with the
  102. contents of the color select register to form another number.  For
  103. example, suppose:
  104.  
  105.     attribute = 13
  106.     palreg[13] = 1Bh
  107.     CSR = 3
  108.  
  109. Attribute 13 selects palette register 13, which contains 1BH.  The color
  110. select register contains 3. We put the contents of the color select
  111. register in bits 6-7 of the final number, and the contents of palreg[13]
  112. in bits 0-5:
  113.  
  114.     3  1B
  115.     -  --
  116.     11 011011
  117.  
  118. The resulting number is 11011011 binary, 219 decimal.  This number
  119. selects one of the 256 video DAC color registers.
  120.  
  121. A C-like formula for the video DAC color resgister selection is:
  122.  
  123.     r = (p[a] & 0x3F) | ((c << 6) & 0xC0)
  124.  
  125. where r is the DAC color register number, p[] is the array of 16 palette
  126. registers, a is the attribute number (0..15), and c is the current
  127. contents of the color select register.
  128.  
  129. The color that will be displayed is the color defined by the selected
  130. video DAC color register (DAC stands for Digital-to-Analog Converter).
  131. Each video DAC register is an 18-bit register that contains three 6-bit
  132. values: one for each of the red, green, and blue primary colors.  Each
  133. value specifies the intensity of that primary color on the screen.  A
  134. zero for a primary means that it's not included in the color; 63 is
  135. maximum intensity.
  136.  
  137. Suppose, in our example, that video DAC register 219 contains the
  138. numbers 0, 3FH, and 3FH (it's convenient to think of the register as
  139. three 6-bit values rather than one 18-bit value).  This means that red
  140. will be off, and green and blue will be at maximum intensity.  The color
  141. displayed by attribute 13 will be bright cyan.
  142.  
  143. Notice that you could change the color of a character with FG attribute
  144. N in four different ways:
  145.  
  146.     1. Change the attribute
  147.     2. Change the contents of palreg[N]
  148.     3. Change the contents of the video DAC register specified by
  149.        palreg[N] and the color select register
  150.     4. Change the contents of the color select register
  151.  
  152. These all have different effects on the total screen display.  Changing
  153. an attribute affects a single character; changing a palette register
  154. affects all characters with that attribute; changing a video DAC
  155. register affects any character whose attribute, when combined with color
  156. select, selects that register--this could be several attributes;
  157. changing the color select register could very well affect everything on
  158. the screen.
  159.  
  160.  
  161. Another way to visualize color selection
  162. ----------------------------------------
  163. There is a simpler way to look at the process.  The two bits used from
  164. the color select register always end up in the high two bits of the
  165. video DAC color register number.  Thus, the selected DAC color register
  166. will always be one of:
  167.  
  168.     CSR=0: 00xx xxxx  (register range 0-63)
  169.     CSR=1: 01xx xxxx  (64-127)
  170.     CSR=2: 10xx xxxx  (128-191)
  171.     CSR=3: 11xx xxxx  (192-255)
  172.  
  173. The remaining 6 bits come directly from the selected palette register.
  174.  
  175. If we break the 256 video DAC color registers into four palettes of 64
  176. colors each, as follows:
  177.  
  178.     DAC registers   Palette
  179.          0-63          0
  180.        64-127          1
  181.       128-191          2
  182.       192-255          3
  183.  
  184. then the color select register selects one of the four 64-color
  185. palettes, and the palette register (which is selected by the attribute)
  186. selects one of the 64 colors of the CSR-selected palette.
  187.  
  188. Thus, it's simply stated:  the attribute selects one of the 64 colors
  189. available from the palette selected by the color select register.
  190.  
  191.  
  192. Mode 1
  193. ------
  194. I mentioned that the above represents one of the two modes supported by
  195. the attribute controller; call it "mode 0".  The other mode (mode 1) is
  196. very similar; the only difference is in which bits are combined from the
  197. palette register and the color select register.  The simplified diagram
  198. is as follows:
  199.  
  200.               attribute 0-15
  201.                   |
  202.                   | selects
  203.                   |
  204.          palette register 0-15     color select register
  205.                   |                         |
  206.                   |                         |
  207.                   | bits 0-3       bits 4-7 |
  208.                   +------------+------------+
  209.                                |
  210.                                | selects
  211.                                |
  212.                  video DAC color register 0-255
  213.  
  214. The difference is that there are four bits each from the palette
  215. register and the color select register (instead of 6 and 2 under the
  216. mode 0).
  217.  
  218. A C-like formula for the video DAC color resgister selection in mode 1:
  219.  
  220.     r = (p[a] & 0x0F) | ((c << 4) & 0xF0)
  221.  
  222. The effect of mode 1 is that the 256 video DAC color registers are
  223. broken down into sixteen 16-color palettes instead of four 64-color
  224. palettes:
  225.  
  226.     DAC registers   Palette
  227.          0-15          0
  228.         16-31          1
  229.         32-47          2
  230.          ...
  231.       240-255         15
  232.  
  233. The palette register (still selected by the attribute) selects one of
  234. the 16 colors available in the palette selected by the current color
  235. select register.
  236.  
  237. The more complex effects (graded color changes, pulsing, etc.) of the
  238. demo program DEMO1 are generated under mode 1. This is because all 256
  239. colors defined by the video DAC color registers can be accessed by
  240. simply changing the contents of the color select register, which is very
  241. efficient (it takes about 1/100th of a second).
  242.  
  243. Under mode 0, only 75% of the available colors can be accessed by just
  244. changing the color select register (this is because there are 64 colors
  245. per palette, but only 16 attributes).  To get to the remaining colors,
  246. you have to change the palette registers.  But there are 16 palette
  247. registers; if you need to alter more than one displayed color, this is
  248. less efficient than using the color select register.
  249.  
  250.  
  251. A mode 1 technique
  252. ------------------
  253. As mentioned, there are a number of ways to alter displayed colors.  I
  254. will concentrate on one technique: creating a series of palettes and
  255. then switching palettes by systematically changing the contents of the
  256. color select register.  This document concentrates on mode 1; some of
  257. the same effects (such as periodic intensification and simulated
  258. blinking) can be obtained in mode 0.
  259.  
  260. Note that the use of mode 1 largely dictates that you must reinitialize
  261. the palette registers.  The VGA BIOS initializes some of these registers
  262. with values greater than 15; these will be masked in mode 1 to the low
  263. 4 bits, yielding values in the range 0..15.  These values will probably
  264. not result in the colors you intend (two attributes will yield red
  265. foreground, for example).  The simplest solution is to just fill the
  266. palette registers sequentially with numbers from 0..15; this largely
  267. causes the palregs to drop out of the picture:  attribute N will map
  268. directly to color N within the palette selected by the color select
  269. register.
  270.  
  271. Assuming that the palette registers are set as described, create a
  272. "base" palette in palette 0. That is, fill palette 0 (video DAC color
  273. registers 0-15) with 16 base color definitions.  It makes sense to set
  274. the standard color combinations for the 16 CGA-like colors that people
  275. will expect to see (color intensity values in hex):
  276.  
  277.     DAC regs  Attr  R   G   B   Color
  278.       0-2      0    0   0   0   Black
  279.       3-5      1    0   0  2A   Blue
  280.       6-8      2    0  2A   0   Green
  281.       9-11     3    0  2A  2A   Cyan
  282.       12-14    4   2A   0   0   Red
  283.       15-17    5   2A   0  2A   Magenta
  284.       18-20    6   2A  2A   0   Brown
  285.       21-23    7   2A  2A  2A   White
  286.       24-26    8    0   0  15   "Gray" (not really)
  287.       27-29    9    0   0  3F   Bright blue
  288.       30-32   10    0  3F   0   Bright green
  289.       33-35   11    0  3F  3F   Bright cyan
  290.       36-38   12    3F  0   0   Bright red
  291.       39-41   13    3F  0  3F   Bright magenta
  292.       42-44   14    3F 3F   0   Yellow
  293.       45-47   15    3F 3F  3F   Intense white
  294.  
  295. (In practice, I use 33h in place of 3Fh.  This leaves some room to flash
  296. even the bright colors by intensification.)
  297.  
  298. The second step is to duplicate palette 0 into palettes 1-15, and then
  299. vary the color definitions for attributes of interest in some systematic
  300. way.  For example, let's specify that attribute 1 is not going to be
  301. "blue"; it's going to be a green that continuously cycles from normal
  302. intensity to high intensity and back.  The effect is similar to flashing
  303. text, but more subtle.  To do this, set the colors for attribute 1 in
  304. each of the palettes as follows:
  305.  
  306.     Palette  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  307.       R      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  308.       G     2A 2C 2E 31 33 35 36 37 38 39 3A 3B 3C 3D 3E 3F
  309.       B      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  310.  
  311. Note that the intensity of the green primary slowly increases from
  312. normal (2A) in palette 0 to maximum intensity (3F) in palette 1. Also
  313. note that attribute 1 no longer has anything to do with blue--it's
  314. green.  (See below for information on how to set a video DAC color
  315. register definition.)
  316.  
  317. If these values are loaded into the video DAC color registers, and you
  318. then sequence through the palettes in a cyclical pattern (0->15->0),
  319. characters with attribute 1 will slowly "pulse" from green to bright
  320. green.  The effect is more subtle--and readable--than simply switching
  321. the characters off and on.
  322.  
  323. The palette change is easily and efficiently accomplished by setting the
  324. color select register--say, in a timer tick intercept routine.  Using a
  325. timer intercept is an ideal way to accomplish this sort of special
  326. effect.  Unlike hardware flashing, the special effects described in this
  327. document must be accomplished by your software.  Using an externally
  328. triggered routine allows this to occur in background; you simply set up
  329. the attributes the way you want them and then go about your work.  The
  330. special effects will continue to be generated even when you're in DOS or
  331. BIOS, say, waiting for a keystroke.  The skeleton for a typical timer
  332. routine might be (assume that DELTA, COUNT, and RESET are all
  333. initialized to 1):
  334.  
  335.     count = count - 1
  336.     if count = 0 then
  337.         palette = palette+delta
  338.         if palette > 15 then
  339.             palette = 15
  340.             delta = -delta
  341.         else if palette < 0 then
  342.             palette = 0
  343.             delta = -delta
  344.         end
  345.         set color select register to palette
  346.         count = reset
  347.     end
  348.  
  349. This is both efficient and flexible:  the blink rate can be adjusted by
  350. altering the values of either DELTA and RESET (or both).  Increasing
  351. DELTA causes the blink rate to speed up by skipping palettes; increasing
  352. RESET slows the blinking by skipping clock ticks.  Be sure that PALETTE
  353. and DELTA are treated as signed numbers.  (Note that FLASH1 uses a
  354. slughtly fancier technique.)
  355.  
  356.  
  357. Effects
  358. -------
  359. Many "special effects" are possible using this technique.  "Pulsing" has
  360. already been discussed; here are some others:
  361.  
  362.  
  363. PERIODIC INTENSIFICATION
  364.  
  365. Pulsing is a gradual change from a low intensity color to a high
  366. intensity color.  The effect can be hardened by using the normal color
  367. for half of the palettes and an intnsified version for the other half.
  368. For example, the following palettes flash cyan to bright cyan:
  369.  
  370.     Palette  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  371.       R      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  372.       G     2A 2A 2A 2A 2A 2A 2A 2A 3F 3F 3F 3F 3F 3F 3F 3F
  373.       B     2A 2A 2A 2A 2A 2A 2A 2A 3F 3F 3F 3F 3F 3F 3F 3F
  374.  
  375. The effect can be varied by altering the ratio of low intensity palettes
  376. to high intensity palettes ("beacons", below, are simply extreme cases
  377. of periodic intensification).
  378.  
  379.  
  380. COLOR CHANGES
  381.  
  382. Another effect is to flash text from one color to another.  This set of
  383. palettes flashes bright green text to bright red.  It's quite an eye
  384. catcher:
  385.  
  386.     Palette  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  387.       R      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  388.       G     3F 3F 3F 3F 3F 3F 3F 3F  0  0  0  0  0  0  0  0
  389.       B      0  0  0  0  0  0  0  0 3F 3F 3F 3F 3F 3F 3F 3F
  390.  
  391.  
  392. GRADED COLOR CHANGES
  393.  
  394. An interesting effect is to "grade" one color into another.  Rather than
  395. simply flashing green to red, change it gradually by fading out the
  396. green primary and fading in the red:
  397.  
  398.     Palette  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  399.       R      0  2  4  6  9 0C 0F 12 15 18 1B 1E 21 24 27 2A
  400.       G     2A 27 24 21 1E 1B 18 15 12 0F 0C  9  6  4  2  0
  401.       B      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  402.  
  403. This attribute will still change from green to red, but the change is
  404. not instantaneous; it slowly fades from one color to the other, passing
  405. through various other unnamed colors (all combinations of red and green)
  406. on the way.
  407.  
  408.  
  409. SIMULATED FLASHING
  410.  
  411. Regular hardware flashing can be simulated via a variant of the above
  412. scheme; simply use the background color for half of the palettes (or the
  413. foreground color, if you want to flash the background):
  414.  
  415.     Palette  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  416.       R     3F 3F 3F 3F 3F 3F 3F 3F  0  0  0  0  0  0  0  0
  417.       G     3F 3F 3F 3F 3F 3F 3F 3F  0  0  0  0  0  0  0  0
  418.       B      0  0  0  0  0  0  0  0 2A 2A 2A 2A 2A 2A 2A 2A
  419.  
  420. The example flashes yellow text if displayed on a blue background.
  421.  
  422.  
  423. SOFTENED FLASHING
  424.  
  425. By placing the background attribute in half of the palettes (as for
  426. flashing) and fading out the foreground in the other half, a softer
  427. version of flashing is possible:
  428.  
  429.     Palette  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  430.       R      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  431.       G     2A 24 1E 19 14 0F 0A  5  0  0  0  0  0  0  0  0
  432.       B     2A 24 1E 19 14 0F 0A  5  0  0  0  0  0  0  0  0
  433.  
  434. The example shows softened flashing of cyan text on a black background.
  435. If any of the background primaries are also components of the
  436. foreground color, do not fade those:
  437.  
  438.     Palette  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  439.       R      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  440.       G     2A 24 1E 19 14 0F 0A  5  0  0  0  0  0  0  0  0
  441.       B     2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
  442.  
  443. The example shows softened flashing of cyan on blue.
  444.  
  445.  
  446. FADING
  447.  
  448. This is an even softer version of flashing text.  It fades the foregound
  449. over the full 16 palettes by grading the foregound color into the
  450. background color.
  451.  
  452.     Palette  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  453.       R      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  454.       G     2A 27 24 21 1E 1B 18 15 12 0F 0C  9  6  4  2  0
  455.       B      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  456.  
  457. The example fades a green foreground into a black background.  If the
  458. background is a color other than black, just use a graded color change
  459. from the FG color to the BG color.
  460.  
  461.  
  462. STROBES AND BEACONS
  463.  
  464. These are two final sample effects.  A strobe is a color that's
  465. invisible most of the time (BG=FG) but flashes briefly to maximum
  466. intensity.  The follow palettes strobe yellow when used with a blue
  467. background:
  468.  
  469.     Palette  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  470.       R      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 3F
  471.       G      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 3F
  472.       B     2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A  0
  473.  
  474. A beacon is a low intensity color that briefly flashes to maximum
  475. intensity.  The following palletes create a blue beacon:
  476.  
  477.     Palette  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  478.       R      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  479.       G      0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  480.       B     20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 3F
  481.  
  482. Note to programmers:  if you use the routines provided in FLASH1.ASM,
  483. note that only palettes that are a multiple of DELTA are ever used.
  484. E.g., if DELTA is 2, palette 15 will not be used; put the strobe or
  485. beacon color in palette 14 instead.
  486.  
  487.  
  488. Advantages/disadvantages
  489. ------------------------
  490. Creating special effects in this manner has several advantages over
  491. using hardware effects (such as flashing), and some disdvantages.  Among
  492. the advantages are:
  493.  
  494.     - MANY more effects are possible; I have mentioned only a few of the
  495.       possibilities.
  496.     - Transition rates are under your control; the hardware blink rate
  497.       is fixed.
  498.     - Effects can be mixed on one screen (one attribute could be a
  499.       strobe, another a graded color change).
  500.     - Any effect can be applied to background as well as foreground.
  501.  
  502. Among the disadvantages are:
  503.  
  504.     - Additional programming effort is required, along with increased
  505.       code and data storage.
  506.     - A background timer routine, if used, has some effect on system
  507.       efficiency (but it's small).
  508.     - Effects are associated with attribute numbers, not with bit
  509.       positions.
  510.  
  511. The last one bears some explanation.  Hardware blinking is associated
  512. with a single bit (bit 7) of the FG/BG attribute byte.  Thus, you have
  513. 16 FG colors, all of which can be flashed.  Software-controlled special
  514. effects, however, are associated with attributes.  If you set, say,
  515. attribute 6 to be pulsed green, you no longer have a brown attribute
  516. available.  Thus, the number of effective "base" colors is reduced for
  517. each special effect attribute you create.
  518.  
  519.  
  520. Mode 0
  521. ------
  522. I have covered attribute control mode 1 in some detail, but some of the
  523. same effects can be accomplished in mode 0.  The primary difference is
  524. that you have only four palettes to work with.  The simpler effects such
  525. as color changes, periodic intensification, and simulated blink can
  526. easily be accomplished in mode one by putting the second color in
  527. palette 1, and then alternating between palettes 0 and 1.
  528.  
  529. More complex effects would require periodic alterations to the palette
  530. registers and/or color plane enable register.
  531.  
  532.  
  533. Programming
  534. -----------
  535. The programming required to accomplish these special effects is
  536. relatively straightforward.  The VGA BIOS provides all necessary
  537. services; no register-level progamming is required (but see the next
  538. section). Useful BIOS services are described below.
  539.  
  540. The only element that might need clarification is how to alter a color
  541. definition in a video DAC color register.  BIOS provides services to set
  542. a single color (BIOS video function 10h, subfunction 10h) and to set a
  543. whole block of colors (function 10h, subfunction 12h).  If you are
  544. altering a few colors only, setting them individually is efficient, but
  545. it's more efficient to update larger numbers of colors by reloading the
  546. entire set of registers.
  547.  
  548. Video function 10h, subfunction 17h reads a block of DAC color registers
  549. into memory allocated by your program.  Each 18-bit register is split
  550. into three bytes, one for each of the red, green, and blue primaries (in
  551. that order).  If you read all 256 registers, 3*256 or 768 bytes of
  552. storage will be required.
  553.  
  554. To obtain the video DAC register number for a particular color in a
  555. particular palette, the formula is:
  556.  
  557.     r = 64*p + pr[a]  (mode 0)
  558.     r = 16*p + pr[a]  (mode 1)
  559.  
  560. where r=register number, p=palette number, pr[] is the array of 16
  561. palette registers, and a=attribute number.
  562.  
  563. The array of palette registers can be read and set via video function
  564. 10, subfunctions 9 and 2 respectively.  Note that if you have set the
  565. palette registers sequentially (pr[0]=0, pr[1]=1,...,pr[15]=15), then
  566. they drop out of the picture for calculation purposes, and the formula
  567. becomes:
  568.  
  569.     r = 64*p + a  (mode 0)
  570.     r = 16*p + a  (mode 1)
  571.  
  572. To locate the offset of the 3-byte color definition for a specific
  573. video DAC color register within the table described above:
  574.  
  575.     o = r * 3
  576.  
  577. where r is the register number described above.
  578.  
  579. A combined formula that locates an absolute address of the definition
  580. of a particular attribute/palette combination:
  581.  
  582.     address = base + 64*p + pr[a] (mode 0)
  583.     address = base + 16*p + pr[a] (mode 1)
  584.  
  585. where base is the base address of the table.  The function GET_DAC_PTR
  586. in FLASH1.ASM performs this calculation.
  587.  
  588. To alter the displayed color for a palette/register combination,
  589. calculate the address of its definition, alter the R/G/B bytes as
  590. desired, and use video BIOS function 10h, subfunction 12h.  Because
  591. this sunfunction can reload the entire set of DAC color registers,
  592. you can alter as many registers as you want in one shot.
  593.  
  594. To alter the definitions for a particular attribute in all 16 palettes,
  595. just locate the first one (palette 0).  The definitions for subsequent
  596. palettes will follow at intervals of 16*3 or 48 (30h) bytes in mode 1,
  597. or at intervals of 64*3 bytes in mode 0. For example, if the mode 1
  598. definition for attribute 8 in palette 0 is at 1000h, attribute 8 in
  599. palette 1 will be at 1030h, in palette 2 at 1060h, etc.
  600.  
  601.  
  602. Changing the current palette (color select register)
  603. ----------------------------------------------------
  604. A palette is selected by setting the contents of the color select
  605. register to the desired palette number.  This can be done by using a
  606. BIOS video service as described below (int 10H, function 10H,
  607. subfunction 13h, BL=1).  This takes about 1/100th of a second and can
  608. easily be done from within a timer intercept routine without any real
  609. problems.
  610.  
  611. However, you may want to set the color select register using register
  612. level programming, for one reason:  programs such as screen blankers may
  613. be watching for BIOS video activity.  If you use BIOS services to change
  614. the palette 18 times a second, your user's screen will never blank.  The
  615. technique is shown in the timer routine in FLASH1.ASM.  It is assembled
  616. only if the equate USE_BIOS is zero during assembly.  If USE_BIOS is
  617. nonzero, FLASH1 is assembled to use the BIOS service for palette
  618. switching.  There is no significant difference in efficiency between
  619. using BIOS and programming the registers yourself; most of the time is
  620. spent in waiting for a video retrace (and you thought you were through
  621. with that when you got rid of your CGA, didn't you).
  622.  
  623. The demo (DEMO1.ASM) was assembled with USE_BIOS off.
  624.  
  625.  
  626. The linkable object module
  627. --------------------------
  628. FLASH1.OBJ(ASM) provides a linkable object module that can be used to
  629. generate all of the special effects described above, and others.
  630.  
  631. The module is organized for COM files; adjusting for other models should
  632. be relatively painless.  The primary assumption is that DS=ES; there is
  633. no assumption that CS=DS (except in the timer intercept), or any
  634. explicit use of the stack.
  635.  
  636. The module prologue describes the services available.  Be sure to call
  637. FLASH_INIT when you start and FLASH_TERM when you exit.
  638.  
  639. The demo program (DEMO1.ASM) demonstrates use of the module.
  640.  
  641.  
  642. BIOS services
  643. --------------
  644. The VGA BIOS supports all necessary manipulation of VGA registers,
  645. including the ability to read register contents (for state restoration
  646. when you are done).  All of the following are accessed through the
  647. standard video BIOS service call (int 10h), function 10h.  To use video
  648. BIOS:
  649.  
  650.     ; Set reg AL and others as needed
  651.     mov ah,10h
  652.     int 10h
  653.  
  654. Most of these functions are reasonably efficient.  An operation such as
  655. setting the color select register can easily be accomplished within an
  656. interrupt service routine.
  657.  
  658.  
  659. PALETTE REGISTERS
  660.  
  661.     Read one palette register
  662.         Entry:
  663.             AL=7
  664.             BL=palette register number (0-15)
  665.         Return:
  666.             BH=palette register value
  667.  
  668.     Set one palette register
  669.         Entry:
  670.             AL=0
  671.             BH=color value
  672.             BL=palette register number (0-15)
  673.         Return:
  674.             none
  675.  
  676.     Read all palette registers
  677.         Entry:
  678.             AL=9
  679.             ES:DX -> 17-byte buffer
  680.         Return:
  681.             ES:DX[0..15] = current palette regs
  682.             ES:DX[16] = current overscan (border) color value
  683.  
  684.     Set all palette registers
  685.         Entry:
  686.             AL=2
  687.             ES:DX -> 17-byte buffer (formatted as for function 9)
  688.         Return:
  689.             None
  690.  
  691.  
  692. VIDEO DAC REGISTERS
  693.  
  694.     Read one video DAC register
  695.         Entry:
  696.             AL=15h
  697.             BX=register number (0..255)
  698.         Return:
  699.             CH=green intensity (0..63)
  700.             CL=blue intensity (0..63)
  701.             DH=red intensity (0..63)
  702.  
  703.     Set one video DAC register
  704.         Entry:
  705.             AL=10h
  706.             BX=register number (0..255)
  707.             CH=green intensity (0..63)
  708.             CL=blue intensity (0..63)
  709.             DH=red intensity (0..63)
  710.         Return:
  711.             none
  712.  
  713.     Read a block of video DAC registers
  714.         Entry:
  715.             AL=17H
  716.             BX=first register (0..255)
  717.             CX=number of registers
  718.             ES:DX -> buffer
  719.         Return:
  720.             On return, the buffer is filled with video DAC color values.
  721.             The first 3 bytes contain the R/G/B values for the first
  722.             specified register, etc.  The buffer should be of size 3*CX
  723.             or more.  Ensure that BX+CX <= 256.
  724.  
  725.     Seta block of video DAC color registers
  726.         Entry:
  727.             AL=12H
  728.             BX=first register (0..255)
  729.             CX=number of registers
  730.             ES:DX -> buffer
  731.                The buffer is formatted as for function 12H.  Ensure
  732.                that BX+CX <= 256.
  733.         Return:
  734.             None
  735.  
  736. ATTRIBUTE CONTROL MODE/COLOR SELECT REGISTER
  737.  
  738.     Read attribute control mode and color select register
  739.         Entry:
  740.             AL=1AH
  741.         Return
  742.             BL=current attribute control mode (0/1)
  743.             BH=color select register contents
  744.  
  745.     Set attribute control mode
  746.         Entry:
  747.             AL=13H
  748.             BL=0
  749.             BH=attribute control mode (0/1)
  750.         Return:
  751.             None
  752.  
  753.     Set color select register
  754.         Entry:
  755.             AL=13H
  756.             BL=1
  757.             BH=value for color select register (0..3 for attribute
  758.                control mode 0, 0..255 for mode 1).
  759.         Return:
  760.             None
  761.  
  762.  
  763. Author and reference
  764. --------------------
  765. This document and the DEMO1 and FLASH1 modules are by:
  766.  
  767.                              Chris Dunford
  768.                         The Cove Software Group
  769.                               PO Box 1072
  770.                            Columbia MD 21044
  771.                               301/992-9371
  772.                          CompuServe 76703,2002
  773.  
  774. The document is copyright (C) 1989 by the author.  Permission is granted
  775. to distribute freely by electronic or other means, but it may not be
  776. republished without permission.
  777.  
  778. Reference (and a darn good one, too): Programmer's Guide to IBM PC and
  779. PS/2 Video Systems; Richard Wilton, Microsoft Press 1987.
  780.  
  781. 10/09/89
  782.